home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr43 / ppl4p10.zip / MODEM_IO.PAS < prev    next >
Pascal/Delphi Source File  |  1995-02-20  |  7KB  |  279 lines

  1. (*********************************************)
  2. (*                                           *)
  3. (*  Talks to your modem. Called by TERM.PAS  *)
  4. (*                                           *)
  5. (*  This program is donated to the Public    *)
  6. (*  Domain by MarshallSoft Computing, Inc.   *)
  7. (*  It is provided as an example of the use  *)
  8. (*  of the Personal Communications Library.  *)
  9. (*                                           *)
  10. (*********************************************)
  11.  
  12. unit Modem_IO;
  13.  
  14. interface
  15.  
  16. procedure ModemEcho(Port:Integer;Echo:Integer);
  17. function  ModemSendTo(Port:Integer;Pace:Integer;TheString:String):Boolean;
  18. function  ModemWaitFor(Port:Integer;WaitTics:Integer;CaseFlag:Boolean;TheString:String):Char;
  19. procedure ModemCmdState(Port:Integer);
  20. procedure ModemHangup(Port:Integer);
  21. procedure ModemQuiet(Port:Integer;Tics:Integer);
  22.  
  23. implementation
  24.  
  25. uses PCL4P;
  26.  
  27. Type MatchType =
  28.   Record
  29.     Start : Integer;
  30.     Next  : Integer;
  31.   end;
  32.  
  33. Const
  34.   Debug = False;
  35. Var
  36.   MatchString : String;    (* ModemWaitFor() match string *)
  37.   MatchLength : Integer;   (* string length *)
  38.   MatchCount  : Integer;   (* # sub-strings *)
  39.   MatchList   : array[0..9] of MatchType;
  40.  
  41. procedure MatchUpper;
  42. var
  43.   i : Integer;
  44. begin
  45.   for i := 1 to MatchLength do MatchString[i] := UpCase(MatchString[i]);
  46. end;
  47.  
  48. procedure MatchInit(TheString:String);
  49. var
  50.   i : Integer;
  51.   C : Char;
  52. begin
  53.   MatchString := TheString;
  54.   MatchLength := Length(MatchString);
  55.   MatchList[0].Start := 1;
  56.   MatchList[0].Next  := 1;
  57.   MatchCount  := 1;
  58.  
  59.   for i := 1 to MatchLength do
  60.     begin
  61.       C := MatchString[i];
  62.       if C = '|' then
  63.         begin
  64.           (* mark start of next string *)
  65.           MatchList[MatchCount].Start := i + 1;
  66.           MatchList[MatchCount].Next := i + 1;
  67.           MatchCount := MatchCount + 1;
  68.         end
  69.     end;
  70.   if Debug then
  71.     begin
  72.       WriteLn('MatchCount=',MatchCount);
  73.       for i := 0 to MatchCount -1 do
  74.         WriteLn(i,': ','Start=',MatchList[i].Start,', Next=',MatchList[i].Next);
  75.     end
  76. end;
  77.  
  78. function MatchChar(C:Char):Integer;
  79. Var
  80.   i : Integer;
  81.   Start : Integer;
  82.   Next  : Integer;
  83.   NextChar : Char;
  84. Begin
  85.  (* consider each sub-string in turn *)
  86.  for i := 0 to MatchCount-1 do
  87.    begin
  88.       Start := MatchList[i].Start;
  89.       Next := MatchList[i].Next;
  90.       NextChar := MatchString[Next];
  91.       if NextChar = C then
  92.         begin (* char C matches *)
  93.           Next := Next + 1;
  94.           if Next > MatchLength then
  95.             begin
  96.               MatchList[i].Next := Start;
  97.               MatchChar := i;
  98.               exit
  99.             end;
  100.           (* look at next char in this sub-string *)
  101.           NextChar := MatchString[Next];
  102.           if NextChar = '|' then
  103.             begin
  104.               MatchList[i].Next := Start;
  105.               MatchChar := i;
  106.               exit
  107.             end;
  108.           MatchList[i].Next := Next;
  109.         end
  110.       else
  111.         begin
  112.           (* char C does NOT match *)
  113.           MatchList[i].Next := Start;
  114.           (* look again if was not 1st char  *)
  115.           if  Next <> Start then i := i - 1;
  116.         end
  117.    end;
  118.    MatchChar := -1;
  119. end;
  120.  
  121. function BreakTest : Boolean;
  122. begin
  123.   if SioBrkKey then
  124.     begin
  125.       WriteLn('User BREAK');
  126.       BreakTest := True
  127.     end
  128.   else BreakTest := False;
  129. end;
  130.  
  131. procedure ModemEcho(Port:Integer;Echo:Integer);
  132. var
  133.   rc   : Integer;
  134.   Time : LongInt;
  135. begin
  136.   Time := SioTimer;
  137.   repeat
  138.     rc := SioGetc(Port,1);
  139.     if rc >= 0 then write(chr(rc));
  140.   until SioTimer > Time+Echo;
  141. end; (* ModemEcho *)
  142.  
  143. function ModemSendTo(Port:Integer;Pace:Integer;TheString:String):Boolean;
  144. const CR = 13;
  145. var
  146.    rc   : Integer;
  147.    i    : Integer;
  148.    c    : Char;
  149.    Time : LongInt;
  150. begin
  151.    i := 0;
  152.    while i <= Length(TheString) do
  153.       begin
  154.          if BreakTest then
  155.            begin
  156.              ModemSendTo := False;
  157.              exit;
  158.            end;
  159.          (* delay 'Pace' tics *)
  160.          if Pace > 0 then ModemEcho(Port,Pace);
  161.          c := TheString[i];
  162.          i := i + 1;
  163.          case c of
  164.             '^' : begin
  165.                     (* next char is control char *)
  166.                     c := chr( Byte(TheString[i]) - $40);
  167.                     i := i + 1;
  168.                   end;
  169.             '!' : c := chr(CR);
  170.             '~' : begin
  171.                     (* delay 1/2 second *)
  172.                     SioDelay(10);
  173.                     c := ' '
  174.                   end;
  175.              ' ': begin
  176.                     (* delay 1/4 second *)
  177.                     SioDelay(5);
  178.                     c := ' ';
  179.                   end;
  180.          end;
  181.          (* transmit as 7 bit char *)
  182.          rc := SioPutc(Port, chr(ord(c) and $7f));
  183.       end; (* for *)
  184.     ModemSendTo := True;
  185. end; (* SendTo *)
  186.  
  187. function ModemWaitFor(Port:Integer;WaitTics:Integer;CaseFlag:Boolean;TheString:String):Char;
  188. const
  189.   CR = 13;
  190.   LF = 10;
  191. var
  192.   c     : Char;
  193.   i,rc  : Integer;
  194.   Time  : LongInt;
  195.   Len   : Integer;
  196. begin (* WaitFor *)
  197.   Len := Length(TheString);
  198.   MatchInit(TheString);
  199.   if not CaseFlag then MatchUpper;
  200.   Time := SioTimer;
  201.   while SioTimer < Time+WaitTics do
  202.     begin
  203.        (* control-BREAK ? *)
  204.        if BreakTest then exit;
  205.        rc := SioGetc(Port,1);
  206.        if rc < -1 then
  207.          begin
  208.            ModemWaitFor := chr($00);
  209.            exit;
  210.          end;
  211.        if rc >= 0 then
  212.          begin
  213.            c := chr(rc);
  214.            write(c);
  215.            (* case sensitive ? *)
  216.            if not CaseFlag then c := UpCase(c);
  217.            (* does char match ? *)
  218.            rc := MatchChar(c);
  219.            if rc >= 0 then
  220.              begin
  221.                ModemWaitFor := chr($30 + rc);
  222.                exit;
  223.              end
  224.          end
  225.     end; (* while *)
  226.   (* timed out *)
  227.   ModemWaitFor := chr($00);
  228. end; (* ModemWaitFor *)
  229.  
  230. procedure ModemCmdState(Port:Integer);
  231. var
  232.   i, rc : Integer;
  233. begin
  234.   (* delay a bit over 1 second *)
  235.   SioDelay(25);
  236.   (* send escape code 3 times *)
  237.   for i := 1 to 3 do
  238.     begin
  239.       rc := SioPutc(Port,'+');
  240.       SioDelay(5);
  241.     end;
  242.   (* another 1 second delay *)
  243.   SioDelay(25);
  244. end; (* ModemCmdState *)
  245.  
  246. procedure ModemHangup(Port:Integer);
  247. var
  248.   Flag : Boolean;
  249. begin
  250.   ModemCmdState(Port);
  251.   Flag := ModemSendTo(Port,5,'!AT!');
  252.   ModemEcho(Port,10);
  253.   Flag := ModemSendTo(Port,5,'ATH0');
  254. end; (* ModemHangup *)
  255.  
  256. procedure  ModemQuiet(Port:Integer;Tics:Integer);
  257. var
  258.   Time : LongInt;
  259.   rc   : Integer;
  260. begin
  261.   Time := SioTimer;
  262.   repeat
  263.     (* control-BREAK ? *)
  264.     if BreakTest then exit;
  265.     rc := SioGetc(Port,1);
  266.     if rc < -1 then exit;
  267.     if rc >= 0 then
  268.       begin
  269.         Time := SioTimer;
  270.         write(chr(rc));
  271.       end
  272.   until SioTimer >= Time + Tics
  273. end; (* ModemQuiet *)
  274.  
  275. begin
  276.   MatchLength := 0;
  277.   MatchCount  := 0;
  278. end.
  279.